package org.apache.commons.configuration;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import junit.framework.TestCase;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
/**
* Test class for XMLConfiguration. In addition to TestXMLConfiguration this
* class especially tests the hierarchical nature of this class and structured
* data access.
*
* @author Emmanuel Bourg
* @author Mark Woodman
* @author Oliver Heger
* @version $Id: TestHierarchicalXMLConfiguration.java 439648 2006-09-02 20:42:10Z oheger $
*/
public class TestHierarchicalXMLConfiguration extends TestCase
{
/** Test resources directory. */
private static final String TEST_DIR = "conf";
/** Test file #1 **/
private static final String TEST_FILENAME = "testHierarchicalXMLConfiguration.xml";
/** Test file #2 **/
private static final String TEST_FILENAME2 = "testHierarchicalXMLConfiguration2.xml";
/** Test file path #1 **/
private static final String TEST_FILE = TEST_DIR + File.separator + TEST_FILENAME;
/** Test file path #2 **/
private static final String TEST_FILE2 = TEST_DIR + File.separator + TEST_FILENAME2;
/** Test file path #3.*/
private static final String TEST_FILE3 = TEST_DIR + File.separator + "test.xml";
/** File name for saving.*/
private static final String TEST_SAVENAME = "testhierarchicalsave.xml";
/** File path for saving.*/
private static final String TEST_SAVE = "target" + File.separator + TEST_SAVENAME;
/** Instance config used for tests. */
private XMLConfiguration config;
/** Fixture setup. */
protected void setUp() throws Exception
{
config = new XMLConfiguration();
}
private void configTest(XMLConfiguration config)
{
assertEquals(1, config.getMaxIndex("tables.table"));
assertEquals("system", config.getProperty("tables.table(0)[@tableType]"));
assertEquals("application", config.getProperty("tables.table(1)[@tableType]"));
assertEquals("users", config.getProperty("tables.table(0).name"));
assertEquals("documents", config.getProperty("tables.table(1).name"));
Object prop = config.getProperty("tables.table.fields.field.name");
assertTrue(prop instanceof Collection);
assertEquals(10, ((Collection) prop).size());
prop = config.getProperty("tables.table(0).fields.field.type");
assertTrue(prop instanceof Collection);
assertEquals(5, ((Collection) prop).size());
prop = config.getProperty("tables.table(1).fields.field.type");
assertTrue(prop instanceof Collection);
assertEquals(5, ((Collection) prop).size());
}
public void testGetProperty() throws Exception
{
config.setFileName(TEST_FILE);
config.load();
configTest(config);
}
public void testLoadURL() throws Exception
{
config.load(new File(TEST_FILE).getAbsoluteFile().toURL());
configTest(config);
}
public void testLoadBasePath1() throws Exception
{
config.setBasePath(TEST_DIR);
config.setFileName(TEST_FILENAME);
config.load();
configTest(config);
}
public void testLoadBasePath2() throws Exception
{
config.setBasePath(new File(TEST_FILE).getAbsoluteFile().toURL().toString());
config.setFileName(TEST_FILENAME);
config.load();
configTest(config);
}
/**
* Ensure various node types are correctly processed in config.
* @throws Exception
*/
public void testXmlNodeTypes() throws Exception
{
// Number of keys expected from test configuration file
final int KEY_COUNT = 5;
// Load the configuration file
config.load(new File(TEST_FILE2).getAbsoluteFile().toURL());
// Validate comment in element ignored
assertEquals("Comment in element must not change element value.", "Case1Text", config
.getString("case1"));
// Validate sibling comment ignored
assertEquals("Comment as sibling must not change element value.", "Case2Text", config
.getString("case2.child"));
// Validate comment ignored, CDATA processed
assertEquals("Comment and use of CDATA must not change element value.", "Case3Text", config
.getString("case3"));
// Validate comment and processing instruction ignored
assertEquals("Comment and use of PI must not change element value.", "Case4Text", config
.getString("case4"));
// Validate comment ignored in parent attribute
assertEquals("Comment must not change attribute node value.", "Case5Text", config
.getString("case5[@attr]"));
// Validate non-text nodes haven't snuck in as keys
Iterator iter = config.getKeys();
int count = 0;
while (iter.hasNext())
{
iter.next();
count++;
}
assertEquals("Config must contain only " + KEY_COUNT + " keys.", KEY_COUNT, count);
}
public void testSave() throws Exception
{
removeTestSaveFile();
try
{
config.setFileName(TEST_FILE3);
config.load();
File saveFile = new File(TEST_SAVE);
config.save(saveFile);
config = new XMLConfiguration();
config.load(saveFile.toURL());
assertEquals("value", config.getProperty("element"));
assertEquals("I'm complex!", config.getProperty("element2.subelement.subsubelement"));
assertEquals(8, config.getInt("test.short"));
assertEquals("one", config.getString("list(0).item(0)[@name]"));
assertEquals("two", config.getString("list(0).item(1)"));
assertEquals("six", config.getString("list(1).sublist.item(1)"));
}
finally
{
removeTestSaveFile();
}
}
/**
* Tests to save a newly created configuration.
*
*/
public void testSaveNew() throws Exception
{
config.addProperty("connection.url", "jdbc://mydb:1234");
config.addProperty("connection.user", "scott");
config.addProperty("connection.passwd", "tiger");
config.addProperty("connection[@type]", "system");
config.addProperty("tables.table.name", "tests");
config.addProperty("tables.table(0).fields.field.name", "test_id");
config.addProperty("tables.table(0).fields.field(-1).name", "test_name");
config.addProperty("tables.table(-1).name", "results");
config.addProperty("tables.table(1).fields.field.name", "res_id");
config.addProperty("tables.table(1).fields.field(0).type", "int");
config.addProperty("tables.table(1).fields.field(-1).name", "value");
config.addProperty("tables.table(1).fields.field(1).type", "string");
config.addProperty("tables.table(1).fields.field(1)[@null]", "true");
removeTestSaveFile();
try
{
File saveFile = new File(TEST_SAVE);
config.setFile(saveFile);
config.setRootElementName("myconfig");
config.save();
config = new XMLConfiguration();
config.load(saveFile);
assertEquals(1, config.getMaxIndex("tables.table.name"));
assertEquals("tests", config.getString("tables.table(0).name"));
assertEquals("test_name", config.getString("tables.table(0).fields.field(1).name"));
assertEquals("int", config.getString("tables.table(1).fields.field(0).type"));
assertTrue(config.getBoolean("tables.table(1).fields.field(1)[@null]"));
assertEquals("tiger", config.getString("connection.passwd"));
assertEquals("system", config.getProperty("connection[@type]"));
assertEquals("myconfig", config.getRootElementName());
}
finally
{
removeTestSaveFile();
}
}
/**
* Tests to save a modified configuration.
*
*/
public void testSaveModified() throws Exception
{
config.setFile(new File(TEST_FILE3));
config.load();
assertTrue(config.getString("mean").startsWith("This is\n A long story..."));
assertTrue(config.getString("mean").indexOf("And even longer") > 0);
config.clearProperty("test.entity[@name]");
config.setProperty("element", "new value");
config.setProperty("test(0)", "A <new> value");
config.addProperty("test(1).int", new Integer(9));
config.addProperty("list(1).sublist.item", "seven");
config.setProperty("clear", "yes");
config.setProperty("mean", "now it's simple");
config.addProperty("[@topattr]", "available");
config.addProperty("[@topattr]", "successfull");
removeTestSaveFile();
try
{
config.save(new File(TEST_SAVE));
config = new XMLConfiguration();
config.load(TEST_SAVE);
assertFalse(config.containsKey("test.entity[@name]"));
assertEquals("1<2", config.getProperty("test.entity"));
assertEquals("new value", config.getString("element"));
assertEquals("A <new> value", config.getProperty("test(0)"));
assertEquals((short) 8, config.getShort("test(1).short"));
assertEquals(9, config.getInt("test(1).int"));
assertEquals("six", config.getProperty("list(1).sublist.item(1)"));
assertEquals("seven", config.getProperty("list(1).sublist.item(2)"));
assertEquals("yes", config.getProperty("clear"));
assertEquals("now it's simple", config.getString("mean"));
assertEquals("available", config.getString("[@topattr](0)"));
assertEquals("successfull", config.getString("[@topattr](1)"));
}
finally
{
removeTestSaveFile();
}
}
/**
* Tests manipulation of the root element's name.
*
*/
public void testRootElement() throws Exception
{
assertEquals("configuration", config.getRootElementName());
config.setRootElementName("newRootName");
assertEquals("newRootName", config.getRootElementName());
config.setFile(new File(TEST_FILE3));
config.load();
assertEquals("testconfig", config.getRootElementName());
try
{
config.setRootElementName("anotherRootElement");
fail("Setting root element name when loaded from file!");
}
catch(UnsupportedOperationException uex)
{
//fine
}
}
/**
* Helper method that ensures that the test save file has been removed.
*
*/
private void removeTestSaveFile()
{
File saveFile = new File(TEST_SAVE);
if (saveFile.exists())
{
assertTrue(saveFile.delete());
}
}
}